// created by noellynch
// Jun 2, 2009

package com.sceneworker.app.tests;

import java.util.logging.Logger;

import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.image.Texture2D;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.util.TextureManager;
import com.sceneworker.app.SceneWorkerAppMain;

public class RTTApp extends SceneWorkerAppMain {
	private static final Logger logger = Logger.getLogger(RTTApp.class.getName());
	
	 private Box realBox, monkeyBox;
	  private Node fakeScene;
	  private Quaternion rotQuat = new Quaternion();
	  private Quaternion rotMBQuat = new Quaternion();
	  private Vector3f axis = new Vector3f(1, 1, 0.5f);
	  private float angle = 0;
	  private float angle2 = 0;
	  
	private TextureRenderer tRenderer;
	private Texture2D fakeTex;
	  
	public RTTApp() {
		super();
	}

	private		void	makeRealBox() {
		// Setup dimensions for a box
	    Vector3f max = new Vector3f(5, 5, 5);
	    Vector3f min = new Vector3f( -5, -5, -5);

	    // Make the real world box -- you'll see this spinning around..  woo...
	    realBox = new Box("Box", min, max);
	    realBox.setModelBound(new BoundingSphere());
	    realBox.updateModelBound();
	    realBox.setLocalTranslation(new Vector3f(0, 0, 0));
	    //FIX ME: if the box is put into a queue the texture rendering has to be done before the scene rendering!
	    //realBox.setRenderQueueMode(Renderer.QUEUE_OPAQUE);

	    rootNode.attachChild(realBox);
	}
	
	private	void	makeFakeBox() {
		// Setup dimensions for a box
	    Vector3f max = new Vector3f(5, 5, 5);
	    Vector3f min = new Vector3f( -5, -5, -5);

	    
	    // Make a monkey box -- some geometry that will be rendered onto a flat texture.
	    // First, we'd like the box to be bigger, so...
	    min.multLocal(3);
	    max.multLocal(3);
	    monkeyBox = new Box("Fake Monkey Box", min, max);
	    monkeyBox.setModelBound(new BoundingSphere());
	    monkeyBox.updateModelBound();
	    monkeyBox.setLocalTranslation(new Vector3f(0, 0, 0));
	}
	
	private	void	makeFakeScene() {
		// add the monkey box to a node.  This node is a root node, not part of the "real world" tree.
	    fakeScene = new Node("Fake node");
	    fakeScene.setRenderQueueMode(Renderer.QUEUE_SKIP);
	    fakeScene.attachChild(monkeyBox);

	    // Setup our params for the depth buffer
	    ZBufferState buf = display.getRenderer().createZBufferState();
	    buf.setEnabled(true);
	    buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
	    fakeScene.setRenderState(buf);	    
	}
	
	@Override
	protected void simpleInitGame() {
		super.simpleInitGame();
		
		makeRealBox();
		makeFakeBox();
		makeFakeScene();

		// Lets add a monkey texture to the geometry we are going to rendertotexture...
	    TextureState lcl_textureState = display.getRenderer().createTextureState();
	    lcl_textureState.setEnabled(true);
	    Texture tex = TextureManager.loadTexture(
	        RTTApp.class.getClassLoader().getResource(
	        "jmetest/data/images/Monkey.jpg"),
	        Texture.MinificationFilter.Trilinear,
	        Texture.MagnificationFilter.Bilinear);
	    lcl_textureState.setTexture(tex);
	    fakeScene.setRenderState(lcl_textureState);

	    // Ok, now lets create the Texture object that our monkey cube will be rendered to.
	    tRenderer = display.createTextureRenderer(512, 512, TextureRenderer.Target.Texture2D);
	    tRenderer.setBackgroundColor(new ColorRGBA(.667f, .667f, .851f, 1f));
	    fakeTex = new Texture2D();
	    fakeTex.setWrap(Texture.WrapMode.Clamp);
	    if ( tRenderer.isSupported() ) {
	        tRenderer.setupTexture(fakeTex);
	        tRenderer.getCamera().setLocation(new Vector3f(0, 0, 75f));
	    } else {
	        logger.severe("Render to texture not supported!");
	    }

	    // Now add that texture to the "real" cube.
	    lcl_textureState = display.getRenderer().createTextureState();
	    lcl_textureState.setEnabled(true);
	    lcl_textureState.setTexture(fakeTex, 0);

	    // Heck, while we're at it, why not add another texture to blend with.
	    Texture tex2 = TextureManager.loadTexture(
	    		RTTApp.class.getClassLoader().getResource(
	        "jmetest/data/texture/dirt.jpg"),
	        Texture.MinificationFilter.Trilinear,
	        Texture.MagnificationFilter.Bilinear);
	    lcl_textureState.setTexture(tex2, 1);
	    rootNode.setRenderState(lcl_textureState);

	    // Since we have 2 textures, the geometry needs to know how to split up the coords for the second state.
	    realBox.copyTextureCoordinates(0, 1, 1.0f);
	    
	    fakeScene.updateGeometricState(0.0f, true);
	    fakeScene.updateRenderState();
		
	}
	
	
	
	@Override
	protected void simpleRender() {
		super.simpleRender();
		
		tRenderer.render(fakeScene, fakeTex);
	}

	public static void main(String[] args) {
		RTTApp		lcl_main = new RTTApp();
		lcl_main.setConfigShowMode(ConfigShowMode.ShowIfNoConfig);
		lcl_main.start();
	}

}
